#ifndef CDBGridH
#define CDBGridH
//---------------------------------------------------------------------------
#include "CtrlDB.h"
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <DBGrids.hpp>
#include <Grids.hpp>
#include "CEdit.h"
#include <map>
#include <algorithm>
//---------------------------------------------------------------------------
#define COLOR_FIRST_LINE   ( TColor)RGB( 250, 250, 230)
#define COLOR_SECOND_LINE  ( TColor)RGB( 255, 235, 160)
//---------------------------------------------------------------------------
typedef std::map< TColumn*, CCustomEdit*> CMapFind;
//---------------------------------------------------------------------------
typedef struct {
  TField *pField;
  bool    bDescending;
} TSortedFieldBookmark;
//---------------------------------------------------------------------------
class PACKAGE_CTRLDB CDBGrid : public TCustomDBGrid
{
private:
  typedef void __fastcall (__closure *TColResizeEvent)(TObject* Sender, TColumn *pColumn);
  typedef void __fastcall (__closure *TDrawTitle)( TObject *pSender, TColumn *pColumn, const TRect &ARect, TGridDrawState AState);

  TColResizeEvent m_OnColResize;
  TNotifyEvent    m_OnMoveUserCol;
  AnsiString      m_ColAutoResize;
  AnsiString      m_Libelle;
  AnsiString      m_LibelleEc;
  bool            m_ModeStandard;
  bool            m_ReadOnly;
  bool            m_Enabled;
  bool            m_bBicolor;
  bool            m_bCritical;
  bool            m_bSortTable;
  bool            m_bInitSort;
  int             m_HeaderHeight;
  int             m_ColResize;
  int             m_nSizeEspace;
  TStringList    *m_TotalCol;
  TStringList    *m_EcartCol;
  TWinControl    *m_Container;
  TColor          m_Color;
  TColor          m_eColorFirst;
  TColor          m_eColorSecond;
  TLabel         *m_LibelleTotal;
  TLabel         *m_LibelleEcart;
  int             m_nColOnMouseDown; // Numéro de la colonne sur laquelle le bouton de la souris a été enfoncé
  int             m_nToto;
  int             m_nBitsPerPixel;
  bool            m_bWantInsert;
  bool            m_bWantDelete;
  bool            m_bRedrawFlag;
  bool            m_bDescendingIdx;
  TField         *m_pfldCurrentIdx;
  AnsiString      m_Reference;

  TDBGridClickEvent m_pfOnClickEvent;
  TDrawTitle        m_pOnDrawTitle;

  TCustomGroupBox  *m_pwcFind;  // Containeur (groupbox) où seront placé les edits pour la recherche par colonne
  CMapFind          m_mapEdit;  // Un map sur les edits correspondant à chacunes des colonnes
  TSpeedButton     *m_sbNext;   // SpeedButton pour rechercher l'élément suivant
  TSpeedButton     *m_sbPrior;  // SpeedButton pour recherche l'élément précédent
  TColumn          *m_pFindCol; // TColumn sur la colonne en cours de recherche
  bool              m_bDestroyContainer;// TRUE : si le container est en cours de suppression
  TStrings         *m_lstFindUnusedCol; // Liste des colonnes dont on ne désire pas avoir un edit de recherche
  AnsiString        m_strSortUnused; // Liste des colonnes sur lesquelles le tri est impossible

  Currency __fastcall GetTotal     ( const AnsiString strFieldName) const;
  Currency __fastcall GetFieldTotal( TField *pField) const;
  Currency __fastcall GetEcart     ( const AnsiString strFieldName) const;
  Currency __fastcall GetFieldEcart( TField *pField) const;
  CCustomEdit *__fastcall GetFindEdit  ( TField *pfld);

  void __fastcall SetColAutoResize( const AnsiString strValue);
  void __fastcall SetModeStandard ( bool bValue);
  void __fastcall SetHeaderHeight ( int nValue);
  void __fastcall SetTotalCol     ( TStringList *value);
  void __fastcall SetEcartCol     ( TStringList *value);
  void __fastcall SetContainer    ( TWinControl *value);
  void __fastcall SetReadOnly     ( bool bValue);
  void __fastcall SetEnabled      ( bool bValue);
  void __fastcall SetColor        ( TColor eColor);
  void __fastcall SetTotal        ( const AnsiString &strFieldName, const Currency &curValue);
  void __fastcall SetEcart        ( const AnsiString &strFieldName, const Currency &curValue);
  void __fastcall SetFieldTotal   ( TField *pField, const Currency &curValue);
  void __fastcall SetFieldEcart   ( TField *pField, const Currency &curValue);
  void __fastcall SetBicolor      ( bool bValue);
  void __fastcall SetColorFirst   ( TColor eColor);
  void __fastcall SetColorSecond  ( TColor eColor);
  void __fastcall SetSortTable    ( bool bValue);

  void __fastcall ChangeEditPosition  ( void);
  void __fastcall EvTotalColOnChanging( TObject *Sender);
  void __fastcall EvTotalColOnChange  ( TObject *Sender);
  void __fastcall EvEcartColOnChanging( TObject *Sender);
  void __fastcall EvEcartColOnChange  ( TObject *Sender);

  void __fastcall EvOnCellClick( TColumn *pColumn);

  void __fastcall SetFindContainer( TCustomGroupBox *pWinCtrl);
  void __fastcall SetFindUnusedCol( const AnsiString strValue);
  void __fastcall DrawFindEdit( void); // Redession tous les edits pour la recherche
  void __fastcall LocateNext( bool bFirstFind = false); // Positionne sur l'élément suivant
  void __fastcall OnFindEditChange( TObject *pSender);
  void __fastcall OnFindEditKeyPress( TObject *pSender, char &cKey);
  void __fastcall OnFindNextClick( TObject *pSender);
  void __fastcall OnFindPriorClick( TObject *pSender);
  AnsiString __fastcall GetFindUnusedCol( void);
  void __fastcall SortFindEdits( void); // Tri les edits à l'aide du TabOrder

  void __fastcall DeleteTemporaryIndex( void);
  void __fastcall SetTemporaryIndex( TField *pfldIndex);
  bool __fastcall SortColumn( TColumn *pColumn);

protected:
  virtual void __fastcall DrawCell(int ACol, int ARow, const TRect &ARect, TGridDrawState AState);
  virtual TInplaceEdit *__fastcall CreateEditor(void);
  DYNAMIC void __fastcall MouseDown(TMouseButton Button, TShiftState Shift, int X, int Y);
  DYNAMIC void __fastcall MouseUp  (TMouseButton Button, TShiftState Shift, int X, int Y);
  DYNAMIC bool __fastcall CanEditAcceptKey( char cKey);
  DYNAMIC void __fastcall SetEditText( int nCol, int nRow, const AnsiString strValue);
  DYNAMIC void __fastcall ColExit( void);
  DYNAMIC AnsiString __fastcall GetFieldValue( int nACol);
  DYNAMIC void __fastcall KeyPress( char &Key);
  DYNAMIC void __fastcall KeyDown( Word &Key, TShiftState Shift);
  DYNAMIC void __fastcall DoEnter(void);
  DYNAMIC bool __fastcall CanFocus(void);
  DYNAMIC void __fastcall TitleClick( TColumn *pColumn);
  virtual void __fastcall Scroll( int nDistance);
  virtual void __fastcall Notification( TComponent *pComponent, TOperation Operation);

  DYNAMIC bool __fastcall DoMouseWheel( TShiftState Shift, int WheelDelta, const TPoint &MousePos);

  void __fastcall WMPaint( TWMPaint &Msg);
  void __fastcall WMSize ( TWMSize  &Msg);
  void __fastcall WMWindowPosChanged(TWMWindowPosChanged &Msg);
  void __fastcall CMVisibleChanged( TMessage &Msg);
  void __fastcall CMColorChanged( TMessage &Msg);
  void __fastcall WMSetRedraw( TWMSetRedraw &Msg);
  void __fastcall WMVScrollAndWMMouseWheel( TMessage &Msg);
  BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER( WM_PAINT           , TWMPaint           , WMPaint           )
    MESSAGE_HANDLER( WM_SIZE            , TWMSize            , WMSize            )
    MESSAGE_HANDLER( WM_WINDOWPOSCHANGED, TWMWindowPosChanged, WMWindowPosChanged)
    MESSAGE_HANDLER( WM_SETREDRAW       , TWMSetRedraw       , WMSetRedraw       )
    MESSAGE_HANDLER( CM_VISIBLECHANGED  , TMessage           , CMVisibleChanged  )
    MESSAGE_HANDLER( CM_COLORCHANGED, TMessage, CMColorChanged)
    MESSAGE_HANDLER( WM_VSCROLL         , TMessage           , WMVScrollAndWMMouseWheel)
    MESSAGE_HANDLER( WM_MOUSEWHEEL      , TMessage           , WMVScrollAndWMMouseWheel)
  END_MESSAGE_MAP(TCustomDBGrid)

public:
  __fastcall  CDBGrid(TComponent* Owner);
  virtual __fastcall ~CDBGrid(void);

  void __fastcall ShowEditor( void);
  void __fastcall ResizeColumnAutoResize(void);
  void __fastcall MoveColumn(int FromIndex, int ToIndex);
  void __fastcall GetPosColumn(TField *pField, int &nLeft, int &nWidth, bool &bVisible);
  void __fastcall GetPosColumn(const AnsiString &szColName, int &nLeft, int &nWidth, bool &bVisible);
  void __fastcall MoveUserTotal(TField *pField, TWinControl *pWinCtrl);
  void __fastcall MoveUserTotal(const AnsiString &strColName, TWinControl *pWinCtrl);
  void __fastcall MoveUserEcart(TField *pField, TWinControl *pWinCtrl);
  void __fastcall MoveUserEcart(const AnsiString &strColName, TWinControl *pWinCtrl);
  void __fastcall MoveUserLabel(TControl *pWinCtrl);
  void __fastcall RedrawRows( void);
  void __fastcall DefaultDrawTitle( TColumn *pColumn, const TRect &ARect, TGridDrawState AState);

  void __fastcall ClearTotal(const AnsiString &strColName);
  void __fastcall ClearTotal(TField *pField);
  void __fastcall ClearEcart(const AnsiString &strColName);
  void __fastcall ClearEcart(TField *pField);

  bool __fastcall GetTabStop( void) const { return TCustomDBGrid::TabStop; };
  void __fastcall SetTabStop( bool bValue) { TCustomDBGrid::TabStop=bValue; };

  // Efface tous les champs 'edit' utiliser pour la recherche par colonne
  void __fastcall ClearFindEdits( void);

  //permet de changer la valeur de la propriété AutoSelect de tout les champs 'edit' utiliser pour la recherche par colonne
  void __fastcall AutoSelectFindEdits(bool pAutoSelect);

  bool __fastcall SortedField( TField *pField, bool bDecroissant = false);
  void __fastcall GetSortedFieldBookmark( TSortedFieldBookmark &eBookmark);
  void __fastcall SetSortedFieldBookmark( TSortedFieldBookmark &eBookmark);


  __property Canvas;
  __property SelectedRows;
  __property Currency Total  [const AnsiString FieldName] = { read=GetTotal     , write=SetTotal      };
  __property Currency FdTotal[TField    *pField   ] = { read=GetFieldTotal, write=SetFieldTotal };
  __property Currency Ecart  [const AnsiString FieldName] = { read=GetEcart     , write=SetEcart      };
  __property Currency FdEcart[TField    *pField   ] = { read=GetFieldEcart, write=SetFieldEcart };

  __property CCustomEdit *FindEdit[TField *pField] = { read=GetFindEdit };

__published:
  // Attributs (sauf Ime* )
  __property Align;
  __property Anchors;
  __property BorderStyle;
//  #pragma message "A virer apres passage V3"
  __property AnsiString ColAutoResize = { read=m_ColAutoResize, write=SetColAutoResize                   };
  __property bool Bicolor             = { read=m_bBicolor     , write=SetBicolor      , default=false    };
  __property TColor Color             = { read=m_Color        , write=SetColor        , default=clWindow };
  __property TColor ColorFirst        = { read=m_eColorFirst  , write=SetColorFirst   , default=COLOR_FIRST_LINE  };
  __property TColor ColorSecond       = { read=m_eColorSecond , write=SetColorSecond  , default=COLOR_SECOND_LINE };
  __property Columns                  = { stored=false };
  __property Ctl3D;
  __property Cursor;
  __property DataSource;
  __property DefaultDrawing;
  __property DefaultRowHeight;
  __property DragCursor;
  __property DragMode;
  __property bool Enabled             = { read=m_Enabled      , write=SetEnabled      , default=true     };
  __property FixedColor;
  __property Font;
  __property int HeaderHeight         = { read=m_HeaderHeight , write=SetHeaderHeight , default=-1       };
  __property Height;
  __property HelpContext;
  __property Hint;
  __property InplaceEditor;
  __property Left;
  __property AnsiString LibelleTotal  = { read=m_Libelle      , write=m_Libelle                          };
  __property AnsiString LibelleEcart  = { read=m_LibelleEc    , write=m_LibelleEc                        };
  __property Name;
  __property bool ModeStandard        = { read=m_ModeStandard , write=SetModeStandard , default=false    };
  __property Options;
  __property ParentColor;
  __property ParentCtl3D;
  __property ParentFont;
  __property ParentShowHint;
  __property PopupMenu;
  __property bool ReadOnly            = { read=m_ReadOnly     , write=SetReadOnly     , default=false    };
  __property ShowHint;
  __property bool SortTable           = { read=m_bSortTable   , write=SetSortTable    , default=false    };
  __property AnsiString SortUnused    = { read=m_strSortUnused, write=m_strSortUnused                    };
  __property int SizeEspace           = { read=m_nSizeEspace  , write=m_nSizeEspace   , default=10       };
  __property TabOrder;
  __property bool TabStop             = { read=GetTabStop     , write=SetTabStop      , default=1        };
  __property Tag;
  __property TitleFont;
  __property Top;
  __property TStringList     *TotalCol       = { read=m_TotalCol      , write=SetTotalCol      };
  __property TStringList     *EcartCol       = { read=m_EcartCol      , write=SetEcartCol      };
  __property TWinControl     *TotalContainer = { read=m_Container     , write=SetContainer     };
  __property TCustomGroupBox *FindContainer  = { read=m_pwcFind       , write=SetFindContainer };
  __property AnsiString       FindUnused     = { read=GetFindUnusedCol, write=SetFindUnusedCol };
  __property Visible;
  __property bool WantInsert = { read=m_bWantInsert, write=m_bWantInsert, default=true };
  __property bool WantDelete = { read=m_bWantDelete, write=m_bWantDelete, default=true };
  __property Width;
  __property Row;  
  __property AnsiString Reference = { read=m_Reference, write=m_Reference };
  // Evènements
  __property TDBGridClickEvent OnCellClick = { read=m_pfOnClickEvent, write=m_pfOnClickEvent };
  __property OnColEnter;
  __property OnColExit;
  __property TColResizeEvent OnColResize = { read=m_OnColResize, write=m_OnColResize };
  __property OnColumnMoved;
  __property OnDblClick;
  __property OnDragDrop;
  __property OnDragOver;
  __property OnDrawColumnCell;
  __property OnDrawDataCell;
  __property TDrawTitle OnDrawTitle = { read=m_pOnDrawTitle, write=m_pOnDrawTitle };
  __property OnEditButtonClick;
  __property OnEndDrag;
  __property OnEnter;
  __property OnExit;
  __property OnKeyDown;
  __property OnKeyPress;
  __property OnKeyUp;
  __property OnMouseDown;
  __property OnMouseMove;
  __property OnMouseUp;
  __property TNotifyEvent OnMoveUserCol = { read=m_OnMoveUserCol, write=m_OnMoveUserCol };
  __property OnStartDrag;
  __property OnTitleClick;

  AnsiString __fastcall GetReference( void);
};
//---------------------------------------------------------------------------
#endif
